package cn.lg.soar.system.biz.filetemplate;

import cn.lg.soar.common.exceptions.BaseException;
import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.common.util.FileTypeUtils;
import cn.lg.soar.common.util.data.DataUtil;
import cn.lg.soar.system.biz.filetemplate.model.GeneratePresignedUrlRequestDTO;
import cn.lg.soar.system.biz.modules.general.entity.FileStorage;
import cn.lg.soar.system.biz.util.FileAccessTokenUtils;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import lombok.SneakyThrows;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author luguoxiang 469599794@qq.com
 * @Date: 2024/3/1 17:25
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class LocalFileTemplateImpl implements FileTemplate {

    private final String rootPath;
    private final int configVersion;
    private final int storageId;

    public LocalFileTemplateImpl(FileStorage storage) {
        this.rootPath = storage.getEndpoint();
        this.configVersion = storage.getVersion();
        this.storageId = storage.getId();
        File file = new File(this.rootPath);
        if (!file.exists()) {
            AssertUtil.isTrue(file.mkdirs(), "创建目录失败");
        }
    }

    @Override
    public void upload(String directory, String filename, InputStream stream) {
        // 指定目标文件的路径
        Path filePath = Paths.get(getFilePath(directory, filename));
        try {
            Files.copy(stream, filePath, StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    @SneakyThrows
    public String getAccessUrl(String directory, String filename, long expire) {
        return FileAccessTokenUtils.createTempUrl(storageId, directory, filename, expire);
    }

    @Override
    public String getAccessUrl(String directory, String filename) {
        return FileAccessTokenUtils.createProxyUrl(storageId, directory, filename);
    }

    @Override
    @SneakyThrows
    public void removeFile(String directory, String filename) {
        String filePath = getFilePath(directory, filename);
        Files.deleteIfExists(Paths.get(filePath));
    }

    @Override
    @SneakyThrows
    public InputStream getInputStream(String directory, String filename) {
        String filePath = getFilePath(directory, filename);
        File file = new File(filePath);
        if (!file.exists()) {
            throw new AmazonS3Exception("The specified key does not exist.");
        }
        return Files.newInputStream(file.toPath());
    }

    @Override
    @SneakyThrows
    public S3Object getFile(String directory, String filename) {
        String filePath = getFilePath(directory, filename);
        File file = new File(filePath);
        if (!file.exists()) {
            throw new AmazonS3Exception("The specified key does not exist.");
        }
        S3Object object = new S3Object();
        object.setBucketName(directory);
        object.setObjectContent(Files.newInputStream(file.toPath()));
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(FileTypeUtils.getContentType(file));
        metadata.setContentLength(file.length());
        object.setObjectMetadata(metadata);
        return object;
    }

    @Override
    @SneakyThrows
    public List<S3ObjectSummary> getFileList(String prefix) {
        File[] files = new File(rootPath).listFiles();
        if (DataUtil.isEmpty(files)) {
            return Collections.emptyList();
        }
        List<S3ObjectSummary> list = new ArrayList<>(files.length);
        for (File file : files) {
            if (file.isFile() && file.getName().startsWith(prefix)) {
                S3ObjectSummary object = new S3ObjectSummary();
                object.setBucketName("");
                object.setSize(file.length());
                object.setLastModified(new Date(file.lastModified()));
                list.add(object);
            }
        }
        return list;
    }

    @Override
    public boolean isExist(String directory, String filename) {
        String filePath = getFilePath(directory, filename);
        return Files.exists(Paths.get(filePath));
    }

    @Override
    public int getConfigVersion() {
        return configVersion;
    }

    @Override
    public void test() {
        File file = new File(rootPath);
        if (file.exists() || file.mkdirs()) {
            return;
        }
        throw new BaseException("A0404", "目录不可用");
    }

    @Override
    public void disconnect() { }

    @Override
    public URL generatePresignedUrl(GeneratePresignedUrlRequestDTO dto) {
        throw new RuntimeException("待实现");
    }

/*    @Override
    public PartUploadUrlInfoDTO startMultipartUpload(PartUploadStartDTO dto) {
        throw new RuntimeException("待实现");
    }

    @Override
    public void endMultipartUpload(PartUploadEndDTO dto) {
        throw new RuntimeException("待实现");
    }*/

    private String getFilePath(String directory, String filename) {
        directory = rootPath + File.separator + directory;
        File file = new File(directory);
        if (!file.exists()) {
            AssertUtil.isTrue(file.mkdirs(), "创建目录失败");
        }
        return directory + File.separator + filename;
    }

}